package com.pucheng.bracelet.viewmodel.blood_pressure

import androidx.lifecycle.*
import com.blankj.utilcode.util.TimeUtils
import com.blankj.utilcode.util.ToastUtils
import com.clj.fastble.exception.BleException
import com.pucheng.bracelet.R
import com.pucheng.bracelet.app.ble.BleCmd
import com.pucheng.bracelet.app.ble.BleWriteAndNotifyCallback
import com.pucheng.bracelet.app.ble.ClientManager
import com.pucheng.bracelet.app.database.repository.BPRepository
import com.pucheng.bracelet.app.database.repository.Sao2Repository
import com.pucheng.bracelet.app.util.ByteUtils
import com.pucheng.bracelet.app.util.CacheUtil
import com.pucheng.bracelet.app.util.DatetimeUtil
import com.pucheng.bracelet.data.bean.BloodPressureBean
import com.pucheng.bracelet.viewmodel.sao2.Sao2ViewModel
import kotlinx.coroutines.launch
import me.hgj.jetpackmvvm.base.viewmodel.BaseViewModel

class BloodPressureViewModel(private val repository: BPRepository) : BaseViewModel() {
    val bpInfo =
        MutableLiveData<BloodPressureBean>().apply { value = CacheUtil.getBloodPressureInfo() }
    val allDataTo7Day: LiveData<List<BloodPressureBean>> = repository.allDataTo7Day.asLiveData()
    val allData: LiveData<List<BloodPressureBean>> = repository.allData.asLiveData()
    var measureState = MutableLiveData<Boolean>().apply { value = false }
    fun measuredBP() {
        if (measureState.value!!) {
            //停止测量
            ToastUtils.showLong(R.string.stop_measuring)
            stopMeasured()
            return
        }
        measureState.value = true
        ToastUtils.showLong(R.string.start_measuring)
        ClientManager.getInstance()
            .sendControlCmd(BleCmd.MEASURED_BP, object : BleWriteAndNotifyCallback() {
                override fun onCharacteristicChanged(data: ByteArray?) {
                    if (data!![0] == ByteUtils.intToByte(0xFB) && data!![1] == ByteUtils.intToByte(
                            0x12
                        ) && data!![6] == ByteUtils.intToByte(0x03)
                    ) {
                        val time: Long =
                            ByteUtils.byteArrToInt(ByteUtils.subBytes(data, 2, 4)).toLong()
                        val bloodPressureBean = BloodPressureBean(
                            0, data!![7].toInt(), data!![8].toInt(), TimeUtils.millis2String(
                                time,
                                DatetimeUtil.DATE_PATTERN_EE
                            )
                        )
                        bpInfo.value = bloodPressureBean
                        insert(bloodPressureBean)
                        CacheUtil.setBloodPressureInfo(bloodPressureBean)
                    }
                    measureState.value = false
                }

                override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
                }

                override fun onWriteFailure(exception: BleException?) {
                    ToastUtils.showShort("测量失败")
                    measureState.value = false
                }
            })
    }

    private fun stopMeasured() {
        ClientManager.getInstance()
            .sendControlCmd(BleCmd.STOP_MEASURED, object : BleWriteAndNotifyCallback() {
                override fun onCharacteristicChanged(data: ByteArray?) {
//                    if (data!![0] == ByteUtils.intToByte(0xFB) && data!![1] == ByteUtils.intToByte(0x12) && data!![6] == ByteUtils.intToByte(0x03)){
//                        val time :Long= ByteUtils.byteArrToInt(ByteUtils.subBytes(data,2,4)).toLong()
//                        val bloodPressureBean = BloodPressureBean(0,data!![7].toInt(),data!![8].toInt(), TimeUtils.millis2String(time,"yyyy-MM-dd HH:mm:ss"))
//                        bpInfo.value = bloodPressureBean
//                        insert(bloodPressureBean)
//                        CacheUtil.setBloodPressureInfo(bloodPressureBean)
//                    }
//                    measureState.value = false
                }

                override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
                    measureState.value = false
                }

                override fun onWriteFailure(exception: BleException?) {
                }
            })
    }

    fun insert(bloodPressureBean: BloodPressureBean) = viewModelScope.launch {

        repository.insert(bloodPressureBean)
    }

}

class BPModelFactory(private val repository: BPRepository) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(BloodPressureViewModel::class.java)) {
            @Suppress("UNCHECKED_CAST")
            return BloodPressureViewModel(repository) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}